home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / mpatrol.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  12KB  |  518 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12.  
  13.  
  14. #define BGHEIGHT (64)
  15.  
  16. static unsigned char scrollreg[16];
  17. static unsigned char bg1xpos,bg1ypos,bg2xpos,bg2ypos,bgcontrol;
  18. static struct osd_bitmap *bgbitmap[3];
  19. static int flipscreen;
  20.  
  21.  
  22.  
  23. /***************************************************************************
  24.  
  25.   Convert the color PROMs into a more useable format.
  26.  
  27.   Moon Patrol has one 256x8 character palette PROM, one 32x8 background
  28.   palette PROM, one 32x8 sprite palette PROM and one 256x4 sprite lookup
  29.   table PROM.
  30.  
  31.   The character and background palette PROMs are connected to the RGB output
  32.   this way:
  33.  
  34.   bit 7 -- 220 ohm resistor  -- BLUE
  35.         -- 470 ohm resistor  -- BLUE
  36.         -- 220 ohm resistor  -- GREEN
  37.         -- 470 ohm resistor  -- GREEN
  38.         -- 1  kohm resistor  -- GREEN
  39.         -- 220 ohm resistor  -- RED
  40.         -- 470 ohm resistor  -- RED
  41.   bit 0 -- 1  kohm resistor  -- RED
  42.  
  43.   The sprite palette PROM is connected to the RGB output this way. Note that
  44.   RED and BLUE are swapped wrt the usual configuration.
  45.  
  46.   bit 7 -- 220 ohm resistor  -- RED
  47.         -- 470 ohm resistor  -- RED
  48.         -- 220 ohm resistor  -- GREEN
  49.         -- 470 ohm resistor  -- GREEN
  50.         -- 1  kohm resistor  -- GREEN
  51.         -- 220 ohm resistor  -- BLUE
  52.         -- 470 ohm resistor  -- BLUE
  53.   bit 0 -- 1  kohm resistor  -- BLUE
  54.  
  55. ***************************************************************************/
  56. void mpatrol_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  57. {
  58.     int i;
  59.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  60.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  61.  
  62.  
  63.     /* character palette */
  64.     for (i = 0;i < 128;i++)
  65.     {
  66.         int bit0,bit1,bit2;
  67.  
  68.  
  69.         /* red component */
  70.         bit0 = (*color_prom >> 0) & 0x01;
  71.         bit1 = (*color_prom >> 1) & 0x01;
  72.         bit2 = (*color_prom >> 2) & 0x01;
  73.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  74.         /* green component */
  75.         bit0 = (*color_prom >> 3) & 0x01;
  76.         bit1 = (*color_prom >> 4) & 0x01;
  77.         bit2 = (*color_prom >> 5) & 0x01;
  78.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  79.         /* blue component */
  80.         bit0 = 0;
  81.         bit1 = (*color_prom >> 6) & 0x01;
  82.         bit2 = (*color_prom >> 7) & 0x01;
  83.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  84.  
  85.         color_prom++;
  86.     }
  87.  
  88.     color_prom += 128;    /* skip the bottom half of the PROM - not used */
  89.     /* color_prom now points to the beginning of the background palette */
  90.  
  91.  
  92.     /* character lookup table */
  93.     for (i = 0;i < TOTAL_COLORS(0)/2;i++)
  94.     {
  95.         COLOR(0,i) = i;
  96.  
  97.         /* also create a color code with transparent pen 0 */
  98.         if (i % 4 == 0)    COLOR(0,i + TOTAL_COLORS(0)/2) = 0;
  99.         else COLOR(0,i + TOTAL_COLORS(0)/2) = i;
  100.     }
  101.  
  102.  
  103.     /* background palette */
  104.     /* reserve one color for the transparent pen (none of the game colors can have */
  105.     /* these RGB components) */
  106.     *(palette++) = 1;
  107.     *(palette++) = 1;
  108.     *(palette++) = 1;
  109.     color_prom++;
  110.  
  111.     for (i = 1;i < 32;i++)
  112.     {
  113.         int bit0,bit1,bit2;
  114.  
  115.  
  116.         /* red component */
  117.         bit0 = (*color_prom >> 0) & 0x01;
  118.         bit1 = (*color_prom >> 1) & 0x01;
  119.         bit2 = (*color_prom >> 2) & 0x01;
  120.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  121.         /* green component */
  122.         bit0 = (*color_prom >> 3) & 0x01;
  123.         bit1 = (*color_prom >> 4) & 0x01;
  124.         bit2 = (*color_prom >> 5) & 0x01;
  125.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  126.         /* blue component */
  127.         bit0 = 0;
  128.         bit1 = (*color_prom >> 6) & 0x01;
  129.         bit2 = (*color_prom >> 7) & 0x01;
  130.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  131.  
  132.         color_prom++;
  133.     }
  134.  
  135.     /* color_prom now points to the beginning of the sprite palette */
  136.  
  137.     /* sprite palette */
  138.     for (i = 0;i < 32;i++)
  139.     {
  140.         int bit0,bit1,bit2;
  141.  
  142.  
  143.         /* red component */
  144.         bit0 = 0;
  145.         bit1 = (*color_prom >> 6) & 0x01;
  146.         bit2 = (*color_prom >> 7) & 0x01;
  147.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  148.         /* green component */
  149.         bit0 = (*color_prom >> 3) & 0x01;
  150.         bit1 = (*color_prom >> 4) & 0x01;
  151.         bit2 = (*color_prom >> 5) & 0x01;
  152.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  153.         /* blue component */
  154.         bit0 = (*color_prom >> 0) & 0x01;
  155.         bit1 = (*color_prom >> 1) & 0x01;
  156.         bit2 = (*color_prom >> 2) & 0x01;
  157.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  158.  
  159.         color_prom++;
  160.     }
  161.  
  162.     /* color_prom now points to the beginning of the sprite lookup table */
  163.  
  164.     /* sprite lookup table */
  165.     for (i = 0;i < TOTAL_COLORS(1);i++)
  166.     {
  167.         COLOR(1,i) = 128+32 + (*color_prom++);
  168.         if (i % 4 == 3) color_prom += 4;    /* half of the PROM is unused */
  169.     }
  170.  
  171.     color_prom += 128;    /* skip the bottom half of the PROM - not used */
  172.  
  173.     /* background */
  174.     /* the palette is a 32x8 PROM with many colors repeated. The address of */
  175.     /* the colors to pick is as follows: */
  176.     /* xbb00: mountains */
  177.     /* 0xxbb: hills */
  178.     /* 1xxbb: city */
  179.     COLOR(2,0) = 128;
  180.     COLOR(2,1) = 128+4;
  181.     COLOR(2,2) = 128+8;
  182.     COLOR(2,3) = 128+12;
  183.     COLOR(4,0) = 128;
  184.     COLOR(4,1) = 128+1;
  185.     COLOR(4,2) = 128+2;
  186.     COLOR(4,3) = 128+3;
  187.     COLOR(6,0) = 128;
  188.     COLOR(6,1) = 128+16+1;
  189.     COLOR(6,2) = 128+16+2;
  190.     COLOR(6,3) = 128+16+3;
  191. }
  192.  
  193.  
  194.  
  195. /***************************************************************************
  196.  
  197.   Stop the video hardware emulation.
  198.  
  199. ***************************************************************************/
  200. int mpatrol_vh_start(void)
  201. {
  202.     int i,j;
  203.  
  204.  
  205.     if (generic_vh_start() != 0)
  206.         return 1;
  207.  
  208.     /* prepare the background graphics */
  209.     for (i = 0;i < 3;i++)
  210.     {
  211.         /* temp bitmap for the three background images */
  212.         if ((bgbitmap[i] = osd_create_bitmap(256,BGHEIGHT)) == 0)
  213.         {
  214.             generic_vh_stop();
  215.             return 1;
  216.         }
  217.  
  218.         for (j = 0;j < 8;j++)
  219.         {
  220.             drawgfx(bgbitmap[i],Machine->gfx[2 + 2 * i],
  221.                     j,0,
  222.                     0,0,
  223.                     32 * j,0,
  224.                     0,TRANSPARENCY_NONE,0);
  225.  
  226.             drawgfx(bgbitmap[i],Machine->gfx[2 + 2 * i + 1],
  227.                     j,0,
  228.                     0,0,
  229.                     32 * j,(BGHEIGHT / 2),
  230.                     0,TRANSPARENCY_NONE,0);
  231.         }
  232.     }
  233.  
  234.     return 0;
  235. }
  236.  
  237.  
  238.  
  239. /***************************************************************************
  240.  
  241.   Stop the video hardware emulation.
  242.  
  243. ***************************************************************************/
  244. void mpatrol_vh_stop(void)
  245. {
  246.     osd_free_bitmap(bgbitmap[0]);
  247.     osd_free_bitmap(bgbitmap[1]);
  248.     osd_free_bitmap(bgbitmap[2]);
  249.     generic_vh_stop();
  250. }
  251.  
  252.  
  253.  
  254. WRITE_HANDLER( mpatrol_scroll_w )
  255. {
  256.     scrollreg[offset] = data;
  257. }
  258.  
  259.  
  260.  
  261. WRITE_HANDLER( mpatrol_bg1xpos_w )
  262. {
  263.     bg1xpos = data;
  264. }
  265.  
  266.  
  267.  
  268. WRITE_HANDLER( mpatrol_bg1ypos_w )
  269. {
  270.     bg1ypos = data;
  271. }
  272.  
  273.  
  274.  
  275. WRITE_HANDLER( mpatrol_bg2xpos_w )
  276. {
  277.     bg2xpos = data;
  278. }
  279.  
  280.  
  281.  
  282. WRITE_HANDLER( mpatrol_bg2ypos_w )
  283. {
  284.     bg2ypos = data;
  285. }
  286.  
  287.  
  288.  
  289. WRITE_HANDLER( mpatrol_bgcontrol_w )
  290. {
  291.     bgcontrol = data;
  292. }
  293.  
  294.  
  295.  
  296. WRITE_HANDLER( mpatrol_flipscreen_w )
  297. {
  298.     /* screen flip is handled both by software and hardware */
  299.     data ^= ~readinputport(4) & 1;
  300.  
  301.     if (flipscreen != (data & 1))
  302.     {
  303.         flipscreen = data & 1;
  304.         memset(dirtybuffer,1,videoram_size);
  305.     }
  306.  
  307.     coin_counter_w(0,data & 0x02);
  308.     coin_counter_w(1,data & 0x20);
  309. }
  310.  
  311.  
  312. READ_HANDLER( mpatrol_input_port_3_r )
  313. {
  314.     int ret = input_port_3_r(0);
  315.  
  316.     /* Based on the coin mode fill in the upper bits */
  317.     if (input_port_4_r(0) & 0x04)
  318.     {
  319.         /* Mode 1 */
  320.         ret    |= (input_port_5_r(0) << 4);
  321.     }
  322.     else
  323.     {
  324.         /* Mode 2 */
  325.         ret    |= (input_port_5_r(0) & 0xf0);
  326.     }
  327.  
  328.     return ret;
  329. }
  330.  
  331.  
  332.  
  333. static void get_clip(struct rectangle *clip, int min_y, int max_y)
  334. {
  335.     clip->min_x = Machine->drv->visible_area.min_x;
  336.     clip->max_x = Machine->drv->visible_area.max_x;
  337.  
  338.     if (flipscreen)
  339.     {
  340.         clip->min_y = Machine->drv->screen_height - 1 - max_y;
  341.         clip->max_y = Machine->drv->screen_height - 1 - min_y;
  342.     }
  343.     else
  344.     {
  345.         clip->min_y = min_y;
  346.         clip->max_y = max_y;
  347.     }
  348. }
  349.  
  350. static void draw_background(struct osd_bitmap *bitmap,
  351.                             int xpos, int ypos, int ypos_end, int image,
  352.                             int transparency)
  353. {
  354.     struct rectangle clip1, clip2;
  355.  
  356.     get_clip(&clip1, ypos,            ypos + BGHEIGHT - 1);
  357.     get_clip(&clip2, ypos + BGHEIGHT, ypos_end);
  358.  
  359.     if (flipscreen)
  360.     {
  361.         xpos = 256 - xpos;
  362.         ypos = Machine->drv->screen_height - BGHEIGHT - ypos;
  363.     }
  364.     copybitmap(bitmap,bgbitmap[image],flipscreen,flipscreen,xpos,      ypos,&clip1,transparency,128);
  365.     copybitmap(bitmap,bgbitmap[image],flipscreen,flipscreen,xpos - 256,ypos,&clip1,transparency,128);
  366.     fillbitmap(bitmap,Machine->gfx[image*2+2]->colortable[3],&clip2);
  367. }
  368.  
  369. /***************************************************************************
  370.  
  371.   Draw the game screen in the given osd_bitmap.
  372.   Do NOT call osd_update_display() from this function, it will be called by
  373.   the main emulation engine.
  374.  
  375. ***************************************************************************/
  376. void mpatrol_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  377. {
  378.     int offs,i;
  379.  
  380.  
  381.     /* for every character in the Video RAM, check if it has been modified */
  382.     /* since last time and update it accordingly. */
  383.     for (offs = videoram_size - 1;offs >= 0;offs--)
  384.     {
  385.         if (dirtybuffer[offs])
  386.         {
  387.             int sx,sy,color;
  388.  
  389.  
  390.             dirtybuffer[offs] = 0;
  391.  
  392.             sx = offs % 32;
  393.             sy = offs / 32;
  394.  
  395.             color = colorram[offs] & 0x1f;
  396.             if (sy >= 7) color += 32;    /* lines 7-31 are transparent */
  397.  
  398.             if (flipscreen)
  399.             {
  400.                 sx = 31 - sx;
  401.                 sy = 31 - sy;
  402.             }
  403.  
  404.             drawgfx(tmpbitmap,Machine->gfx[0],
  405.                     videoram[offs] + 2 * (colorram[offs] & 0x80),
  406.                     color,
  407.                     flipscreen,flipscreen,
  408.                     8*sx,8*sy,
  409.                     0,TRANSPARENCY_NONE,0);
  410.         }
  411.     }
  412.  
  413.  
  414.     /* copy the background */
  415.     if ((bgcontrol == 0x04) || (bgcontrol == 0x03))
  416.     {
  417.         struct rectangle clip;
  418.  
  419.         get_clip(&clip, 7*8, bg2ypos-1);
  420.         fillbitmap(bitmap,Machine->pens[0],&clip);
  421.  
  422.         draw_background(bitmap, bg2xpos, bg2ypos, bg1ypos + BGHEIGHT - 1, 0, TRANSPARENCY_NONE);
  423.         draw_background(bitmap, bg1xpos, bg1ypos, Machine->drv->visible_area.max_y,
  424.                         (bgcontrol == 0x04) ? 1 : 2, TRANSPARENCY_COLOR);
  425.     }
  426.     else fillbitmap(bitmap,Machine->pens[0],&Machine->drv->visible_area);
  427.  
  428.  
  429.     /* copy the temporary bitmap to the screen */
  430.     {
  431.         int scroll[32];
  432.         struct rectangle clip;
  433.  
  434.  
  435.         clip.min_x = Machine->drv->visible_area.min_x;
  436.         clip.max_x = Machine->drv->visible_area.max_x;
  437.  
  438.         if (flipscreen)
  439.         {
  440.             clip.min_y = 25 * 8;
  441.             clip.max_y = 32 * 8 - 1;
  442.             copybitmap(bitmap,tmpbitmap,0,0,0,0,&clip,TRANSPARENCY_NONE,0);
  443.  
  444.             clip.min_y = 0;
  445.             clip.max_y = 25 * 8 - 1;
  446.  
  447.             for (i = 0;i < 32;i++)
  448.                 scroll[31-i] = -scrollreg[i/2];
  449.  
  450.             copyscrollbitmap(bitmap,tmpbitmap,32,scroll,0,0,&clip,TRANSPARENCY_COLOR,0);
  451.         }
  452.         else
  453.         {
  454.             clip.min_y = 0;
  455.             clip.max_y = 7 * 8 - 1;
  456.             copybitmap(bitmap,tmpbitmap,0,0,0,0,&clip,TRANSPARENCY_NONE,0);
  457.  
  458.             clip.min_y = 7 * 8;
  459.             clip.max_y = 32 * 8 - 1;
  460.  
  461.             for (i = 0;i < 32;i++)
  462.                 scroll[i] = scrollreg[i/2];
  463.  
  464.             copyscrollbitmap(bitmap,tmpbitmap,32,scroll,0,0,&clip,TRANSPARENCY_COLOR,0);
  465.         }
  466.     }
  467.  
  468.  
  469.     /* Draw the sprites. */
  470.     for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  471.     {
  472.         int sx,sy,flipx,flipy;
  473.  
  474.  
  475.         sx = spriteram_2[offs + 3];
  476.         sy = 241 - spriteram_2[offs];
  477.         flipx = spriteram_2[offs + 1] & 0x40;
  478.         flipy = spriteram_2[offs + 1] & 0x80;
  479.         if (flipscreen)
  480.         {
  481.             flipx = !flipx;
  482.             flipy = !flipy;
  483.             sx = 240 - sx;
  484.             sy = 242 - sy;
  485.         }
  486.  
  487.         drawgfx(bitmap,Machine->gfx[1],
  488.                 spriteram_2[offs + 2],
  489.                 spriteram_2[offs + 1] & 0x3f,
  490.                 flipx,flipy,
  491.                 sx,sy,
  492.                 &Machine->drv->visible_area,TRANSPARENCY_COLOR,128+32);
  493.     }
  494.     for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  495.     {
  496.         int sx,sy,flipx,flipy;
  497.  
  498.         sx = spriteram[offs + 3];
  499.         sy = 241 - spriteram[offs];
  500.         flipx = spriteram[offs + 1] & 0x40;
  501.         flipy = spriteram[offs + 1] & 0x80;
  502.         if (flipscreen)
  503.         {
  504.             flipx = !flipx;
  505.             flipy = !flipy;
  506.             sx = 240 - sx;
  507.             sy = 242 - sy;
  508.         }
  509.  
  510.         drawgfx(bitmap,Machine->gfx[1],
  511.                 spriteram[offs + 2],
  512.                 spriteram[offs + 1] & 0x3f,
  513.                 flipx,flipy,
  514.                 sx,sy,
  515.                 &Machine->drv->visible_area,TRANSPARENCY_COLOR,128+32);
  516.     }
  517. }
  518.